# coding=utf-8
from tornado import web, websocket, escape
from datetime import datetime

clients = set()

msg_log = []

class UserMixin:

    @property
    def current_user(self):
        user = self.get_secure_cookie("username")
        if user:
            return user.decode("utf-8")
        else:
            return ""

    def send_msg(self, message, all=True):
        for client in clients:
            if all == False and self.current_user == client.current_user:
                continue
            try:
                client.write_message(message)
            except websocket.WebSocketClosedError:
                pass

    def _make_message(self, template=None, **kwargs):
        message = {
            "type": "sys",
            "username": self.current_user,
            "body": f"欢迎来到聊天室",
            "datetime": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        }
        message.update(kwargs)
        if template:
            message['html'] = escape.to_basestring(
                self.render_string(template, **message)
            )
        return message


class IndexHandler(UserMixin, web.RequestHandler):

    def get(self, *args, **kwargs):

        if not self.current_user:
            self.render("login.html")
        else:
            self.render("index.html", username=self.current_user)

    def post(self, *args, **kwargs):

        username = self.get_body_argument("username")
        self.set_secure_cookie("username", username)

        self.render("index.html", username=self.current_user)


class WSHandler(UserMixin, websocket.WebSocketHandler):

    def open(self, *args, **kwargs):
        global msg_log
        clients.add(self)

        message = self._make_message(
            template="sys_msg.html",
            body=f"{self.current_user} 进入了聊天室",
        )

        message_live = {
            "type": "user",
            "html": "".join([f"<li>{client.current_user}</li>" for client in clients])
        }

        self.send_msg(message)
        self.send_msg(message_live)
        msg_log = msg_log[-3:]
        self.write_message({"html": "".join(msg_log), "type": "sys"})

    def on_message(self, message):

        message = self._make_message(
            template="msg.html",
            type="chat",
            body=escape.json_decode(message)['content']
        )

        self.send_msg(message, all=False)
        msg_log.append(message['html'])

        message['html'] = escape.to_basestring(
            self.render_string("self_msg.html", **message)
        )
        self.write_message(message)

    def on_close(self):
        clients.remove(self)

        message = self._make_message(
            template="sys_msg.html",
            body=f"{self.current_user} 离开了聊天室",
        )

        message_live = {
            "type": "user",
            "html": "".join([f"<li>{client.current_user}</li>" for client in clients])
        }

        self.send_msg(message)
        self.send_msg(message_live)
